/**
 * ESP8266 WiFi模块驱动
 * 使用UART串口通信
 */

#include "esp8266.h"
#include "stdio.h"
#include "string.h"

// 使用USART2连接ESP8266 (PA2=TX, PA3=RX)
#define ESP8266_USART USART2

// 接收缓冲区
#define RX_BUFFER_SIZE 1024
static char rx_buffer[RX_BUFFER_SIZE];
static uint16_t rx_index = 0;

// 全局变量
static ESP8266_Status esp8266_status = ESP8266_DISCONNECTED;
static WiFi_Config wifi_config;

// 私有函数声明
static void ESP8266_USART_Init(void);
static void ESP8266_Clear_Buffer(void);
static uint8_t ESP8266_Wait_For_Response(const char *expected, uint32_t timeout);

// ESP8266初始化
void ESP8266_Init(void) {
    // 初始化串口
    ESP8266_USART_Init();
    
    // 清空缓冲区
    ESP8266_Clear_Buffer();
    
    // 测试AT指令
    if (ESP8266_Send_AT_Command("AT\r\n", "OK", 1000)) {
        printf("ESP8266模块检测成功\r\n");
        
        // 设置为STA模式
        if (ESP8266_Send_AT_Command("AT+CWMODE=1\r\n", "OK", 1000)) {
            printf("ESP8266设置为STA模式\r\n");
        }
        
        // 关闭回显
        ESP8266_Send_AT_Command("ATE0\r\n", "OK", 1000);
        
        esp8266_status = ESP8266_DISCONNECTED;
    } else {
        printf("ESP8266模块检测失败\r\n");
        esp8266_status = ESP8266_ERROR;
    }
}

// USART2初始化
static void ESP8266_USART_Init(void) {
    USART_InitTypeDef USART_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
    
    // USART2配置
    USART_InitStructure.USART_BaudRate = 115200;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
    USART_Init(ESP8266_USART, &USART_InitStructure);
    
    // 使能USART2
    USART_Cmd(ESP8266_USART, ENABLE);
    
    // 配置USART2中断
    USART_ITConfig(ESP8266_USART, USART_IT_RXNE, ENABLE);
    
    NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}

// 清空接收缓冲区
static void ESP8266_Clear_Buffer(void) {
    memset(rx_buffer, 0, RX_BUFFER_SIZE);
    rx_index = 0;
}

// 获取ESP8266状态
ESP8266_Status ESP8266_Get_Status(void) {
    return esp8266_status;
}

// 发送AT指令
uint8_t ESP8266_Send_AT_Command(const char *cmd, const char *expected, uint32_t timeout) {
    // 清空缓冲区
    ESP8266_Clear_Buffer();
    
    // 发送命令
    for (uint16_t i = 0; i < strlen(cmd); i++) {
        while (USART_GetFlagStatus(ESP8266_USART, USART_FLAG_TXE) == RESET);
        USART_SendData(ESP8266_USART, cmd[i]);
    }
    
    // 等待响应
    return ESP8266_Wait_For_Response(expected, timeout);
}

// 等待响应
static uint8_t ESP8266_Wait_For_Response(const char *expected, uint32_t timeout) {
    uint32_t start_time = 0;
    uint32_t current_time = 0;
    
    // 简化的超时等待
    for (uint32_t i = 0; i < timeout * 1000; i++) {
        // 检查缓冲区中是否包含期望的响应
        if (strstr(rx_buffer, expected) != NULL) {
            return 1;
        }
        
        // 简单的延时
        for (uint32_t j = 0; j < 72; j++) {
            __NOP();
        }
    }
    
    return 0;
}

// 连接WiFi
uint8_t ESP8266_Connect_WiFi(const char *ssid, const char *password) {
    char cmd_buffer[128];
    
    // 保存配置
    strcpy(wifi_config.ssid, ssid);
    strcpy(wifi_config.password, password);
    
    // 构建连接命令
    snprintf(cmd_buffer, sizeof(cmd_buffer), "AT+CWJAP=\"%s\",\"%s\"\r\n", ssid, password);
    
    printf("正在连接WiFi: %s\r\n", ssid);
    
    // 发送连接命令
    if (ESP8266_Send_AT_Command(cmd_buffer, "OK", 10000)) { // 10秒超时
        printf("WiFi连接成功\r\n");
        esp8266_status = ESP8266_CONNECTED;
        return 1;
    } else {
        printf("WiFi连接失败\r\n");
        esp8266_status = ESP8266_ERROR;
        return 0;
    }
}

// 连接服务器
uint8_t ESP8266_Connect_Server(const char *ip, uint16_t port) {
    char cmd_buffer[128];
    
    // 保存配置
    strcpy(wifi_config.server_ip, ip);
    wifi_config.server_port = port;
    
    // 启用多连接
    if (!ESP8266_Send_AT_Command("AT+CIPMUX=1\r\n", "OK", 1000)) {
        return 0;
    }
    
    // 建立TCP连接
    snprintf(cmd_buffer, sizeof(cmd_buffer), "AT+CIPSTART=0,\"TCP\",\"%s\",%d\r\n", ip, port);
    
    printf("正在连接服务器: %s:%d\r\n", ip, port);
    
    if (ESP8266_Send_AT_Command(cmd_buffer, "OK", 5000)) {
        printf("服务器连接成功\r\n");
        return 1;
    } else {
        printf("服务器连接失败\r\n");
        return 0;
    }
}

// 发送数据
uint8_t ESP8266_Send_Data(const char *data) {
    char cmd_buffer[256];
    uint16_t data_len = strlen(data);
    
    // 检查连接状态
    if (esp8266_status != ESP8266_CONNECTED) {
        printf("WiFi未连接，无法发送数据\r\n");
        return 0;
    }
    
    // 构建发送命令
    snprintf(cmd_buffer, sizeof(cmd_buffer), "AT+CIPSEND=0,%d\r\n", data_len);
    
    // 发送长度命令
    if (!ESP8266_Send_AT_Command(cmd_buffer, ">", 1000)) {
        printf("准备发送数据失败\r\n");
        return 0;
    }
    
    // 发送实际数据
    for (uint16_t i = 0; i < data_len; i++) {
        while (USART_GetFlagStatus(ESP8266_USART, USART_FLAG_TXE) == RESET);
        USART_SendData(ESP8266_USART, data[i]);
    }
    
    // 等待发送完成
    if (ESP8266_Wait_For_Response("SEND OK", 2000)) {
        printf("数据发送成功: %s\r\n", data);
        return 1;
    } else {
        printf("数据发送失败\r\n");
        return 0;
    }
}

// 处理响应
void ESP8266_Process_Response(char *response) {
    // 解析响应数据
    if (strstr(response, "WIFI CONNECTED")) {
        esp8266_status = ESP8266_CONNECTED;
        printf("WiFi已连接\r\n");
    } else if (strstr(response, "WIFI DISCONNECT")) {
        esp8266_status = ESP8266_DISCONNECTED;
        printf("WiFi已断开\r\n");
    } else if (strstr(response, "CLOSED")) {
        printf("连接已关闭\r\n");
    }
    
    // 这里可以添加更多的响应处理逻辑
}

// USART2中断服务函数
void USART2_IRQHandler(void) {
    if (USART_GetITStatus(ESP8266_USART, USART_IT_RXNE) != RESET) {
        uint8_t data = USART_ReceiveData(ESP8266_USART);
        
        // 存储到接收缓冲区
        if (rx_index < RX_BUFFER_SIZE - 1) {
            rx_buffer[rx_index++] = data;
            rx_buffer[rx_index] = '\0'; // 确保字符串结束
        }
        
        USART_ClearITPendingBit(ESP8266_USART, USART_IT_RXNE);
    }
}
